package 语法.面向对象.元编程

/**
 * groovy调用优先级：methodMissing > methodInvoke >
 * groovy运行流程：
 *  在调用类中方法的时候，如果不存在，但是我们重写了invokeMethod方法，那代码不会报错，会自动去调用实现的invokeMethod方法，invokeMethod方法第一个参数就是调用者方法的名字
 *  当invokeMethod和methodMissing同时存在时候，优先调用methodMissing
 *
 *  metaClass,在代码运行时动态的往里面添加属性和方法
 */

//groovy调用优先级：methodMissing > methodInvoke
def person = new Person(name: 'jml', age: 18);
println person.cry()

//动态的给对象添加属性sex,如果之后创建的对象没有具体给sex赋值，就都默认为male，之前创建好的对象是没有这个属性的
Person.metaClass.sex = 'male'
def p1 = new Person(name: 'jml', age: 18);
println p1.sex
println "--------------------------------------------------"

//动态的给对象添加方法nameUp,通过闭包。这个方法就是把字符串转为大写
Person.metaClass.nameUp = { String oldName-> oldName.toUpperCase()}
def p2 = new Person(name: 'jml', age: 18);
//调用这个方法
println p2.nameUp(p2.name)
println "--------------------------------------------------"

//添加一个静态的方法
Person.metaClass.static.createPerson = {
    String name ,Integer age -> new Person(name:  name,age:  age);
}
//这样动态注入的属性和方法只能在此脚本中使用,在其他脚本中创建Person则是无效的,
//如果要在其他脚本中也要使用，需要在扩展前加入ExpandoMetaClass.enableGlobally();
def p3 = Person.createPerson("jj",19);
println p3.name+p3.age
println "--------------------------------------------------"










